import React, {useCallback, useMemo, useEffect} from 'react'
import {bindActionCreators} from 'redux'
import {connect} from 'react-redux'
import PropTypes from 'prop-types'
import URI from 'urijs'
import dayjs from 'dayjs'
import {h0} from '../common/fp'
import Header from '../common/Header'
import Nav from '../common/Nav'
import List from './List'
import Bottom from './Bottom'
import useNav from '../common/useNav'
import {
  setFrom,
  setTo,
  setDepartDate,
  setHighSpeed,
  setSearchParsed,
  setTrainList,
  setTrainTypes,
  setTicketTypes,
  setDepartStations,
  setArriveStations,
  prevDate,
  nextDate,
  toggleHighSpeed,
  toggleOrderType,
  toggleOnlyTickets,
  toggleIsFiltersOpen,
  setCheckTrainTypes,
  setCheckedTicketTypes,
  setCheckDepartStations,
  setCheckArriveStations,
  setDepartTimeStart,
  setDepartTimeEnd,
  setArriveTimeStart,
  setArriveTimeEnd
} from './actions'

import './App.css'

function App (props) {
  const {trainList,
      from, 
      to, 
      dispatch, 
      departDate, 
      searchParsed, 
      highSpeed, 
      orderType, 
      onlyTickets, 
      isFiltersOpen,
      ticketTypes,
      trainTypes,
      departStations,
      arriveStations,
      checkedTicketTypes,
      checkTrainTypes,
      checkDepartStations,
      checkArriveStations, 
      departTimeStart, 
      departTimeEnd, 
      arriveTimeStart, 
      arriveTimeEnd
    } = props

  const onBack = useCallback(() => {
    window.history.back()
  }, [])

  useEffect(() => {
    const queries = URI.parseQuery(window.location.search)
    const {from, to, highSpeed, date} = queries
    dispatch(setFrom(from))
    dispatch(setTo(to))
    dispatch(setDepartDate(h0(dayjs(date).valueOf())))
    dispatch(setHighSpeed(highSpeed === 'true'))
    dispatch(setSearchParsed(true))
  }, [])

  useEffect(() => {
    if(!searchParsed) return
    const url = new URI('http://localhost:8089/rest/query')
      .setSearch('from', from)
      .setSearch('to', to)
      .setSearch('date', dayjs(departDate).format('YYYY-MM-DD'))
      .setSearch('highSpeed', highSpeed)
      .setSearch('orderType', orderType)
      .setSearch('onlyTickets', onlyTickets)
      .setSearch('checkedTicketTypes', Object.keys(checkedTicketTypes).join())
      .setSearch('checkTrainTypes', Object.keys(checkTrainTypes).join())
      .setSearch('checkDepartStations', Object.keys(checkDepartStations).join())
      .setSearch('checkArriveStations', Object.keys(checkArriveStations).join())
      .setSearch('departTimeStart', departTimeStart)
      .setSearch('departTimeEnd', departTimeEnd)
      .setSearch('arriveTimeStart', arriveTimeStart)
      .setSearch('arriveTimeEnd', arriveTimeEnd)
      .toString()

      fetch(url)
        .then(response => response.json())
        .then(res => {
          const {
            dataMap: {
              directTrainInfo: {
                trains,
                filter: {
                  ticketType,
                  trainType,
                  depStation,
                  arrStation
                }
              }
            }
          } = res
          dispatch(setTrainList(trains))
          dispatch(setTrainTypes(trainType))
          dispatch(setTicketTypes(ticketType))
          dispatch(setDepartStations(depStation))
          dispatch(setArriveStations(arrStation))
        })
  }, [
      searchParsed,
      from,
      to,
      departDate,
      highSpeed,
      orderType, 
      onlyTickets,
      checkedTicketTypes,
      checkTrainTypes,
      checkDepartStations,
      checkArriveStations,
      departTimeStart,
      departTimeEnd,
      arriveTimeStart,
      arriveTimeEnd])
  
  const {isNextDisabled, isPrevDisabled, prev, next} = useNav(departDate,dispatch, prevDate, nextDate)

  const bottomCbs = useMemo(() => {
    return bindActionCreators({
      toggleHighSpeed,
      toggleOrderType,
      toggleOnlyTickets,
      toggleIsFiltersOpen,
      setCheckTrainTypes,
      setCheckedTicketTypes,
      setCheckDepartStations,
      setCheckArriveStations,
      setDepartTimeStart,
      setDepartTimeEnd,
      setArriveTimeStart,
      setArriveTimeEnd
    }, dispatch)
  }, [])

  if(!searchParsed) {
    return null
  }

  return (
    <div>
      <div className="header-wrapper">
        <Header title={`${from} —— ${to}`} onBack={onBack} />
      </div>
      <Nav date={departDate} 
        isPrevDisabled={isPrevDisabled}
        isNextDisabled={isNextDisabled}
        prev={prev}
        next={next} />
      <List list={trainList} />
      <Bottom
        highSpeed={highSpeed}
        orderType={orderType} 
        onlyTickets={onlyTickets} 
        isFiltersOpen={isFiltersOpen}
        ticketTypes={ticketTypes}
        trainTypes={trainTypes}
        departStations={departStations}
        arriveStations={arriveStations}
        checkedTicketTypes={checkedTicketTypes}
        checkTrainTypes={checkTrainTypes}
        checkDepartStations={checkDepartStations}
        checkArriveStations={checkArriveStations}
        departTimeStart={departTimeStart}
        departTimeEnd={departTimeEnd}
        arriveTimeStart={arriveTimeStart}
        arriveTimeEnd={arriveTimeEnd}
       {...bottomCbs}
      />
    </div>
  )
}

export default connect(
  function mapStateToProps (state) {
    return state
  },
  function mapDispatchToProps (dispatch){
    return {dispatch}
  }
)(App)

